package com.oms.app.sequence.service.impl;

import java.util.Hashtable;

import com.oms.app.sequence.dao.ISequenceDAO;
import com.oms.app.sequence.model.Sequence;
import com.oms.base.SpringContextFactory;

/**
 * @author Loong_Mit
 * @date Sep 5, 2012 9:39:42 PM
 */

public class SequenceManager {
	private String m_strTable;
	private int m_iBlockSize = 201;
	private int m_iCurrentID;
	private long m_iMaxID;
	private static Hashtable<String, Object> sequences = new Hashtable<String, Object>(120, 0.9f);
	private ISequenceDAO sequenceDAO = (ISequenceDAO) SpringContextFactory.getBean("sequenceDAO");
	
	public SequenceManager(String table, int blockSize) {
		this.m_strTable = table.toLowerCase();
		this.m_iBlockSize = blockSize;
		m_iCurrentID = 0;
		m_iMaxID = 0;
	}
	
	/**
	 * 取某表(Table)的自动增量ID。
	 * 
	 * @param table
	 *            表名，一个表对应一个自动增量序列，表名不区分大小写。
	 * @return int 自动增量ID以10000为基数，因为某些系统表可能会有初始量，10000为保留ID。
	 */

	public static int nextID(String table) {
		if (table == null)
			return -1;
		table = table.toLowerCase();
		String strKey = table;
		if (sequences.containsKey(strKey)) {
			SequenceManager tmp = (SequenceManager) sequences.get(strKey);
			return tmp.nextUniqueID();
		} else {
			SequenceManager tmp = new SequenceManager(table, 200);
			sequences.put(strKey, tmp);
			return tmp.nextUniqueID();
		}
	}

	private synchronized int nextUniqueID() {
		if (m_iCurrentID >= m_iMaxID) {
			getNextBlock(1);
		}
		int id = m_iCurrentID;
		m_iCurrentID++;
		return id;
	}

	private void getNextBlock(long count) {
		if (count == 0) {
			System.err.println("\n\nFailed at last attempt to obtain an ID, aborting...");
			return;
		}
		boolean success = false;
		Sequence sequence = sequenceDAO.getSequence(m_strTable);
		int currentID = 0;
		if (sequence != null && sequence.getId() != -1) {
			currentID = sequence.getId();
		} else {
			sequenceDAO.insertSequence(m_strTable);
			currentID = 10000;
		}
		int newID = currentID + (int) m_iBlockSize;
		if (sequence == null) {
			sequence = new Sequence();
		}
		sequence.setId(newID);
		int i = sequenceDAO.updateSequence(sequence);
		if (i > 0) {
			success = true;
			if (success) {
				this.m_iCurrentID = currentID;
				m_iMaxID = newID;
			} else {
				String strMsg = "updateSequence----------newID=" + newID + "----------m_strTable=" + m_strTable;
				System.out.println("\n\n error in \n" + strMsg);
				success = true;// 不用休眠。
			}
		}
	}

	public static void clearSequences() {
		sequences = new Hashtable<String, Object>(120, 0.9f);
	}

	public static void main(String[] args) {
		for (int i = 0; i < 10; i++) {
			int id = SequenceManager.nextID("test");
			System.out.println("id[test]:" + id);
		}
	}
}
